home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / tblt / tblt⁄move.c < prev    next >
Text File  |  1986-09-06  |  7KB  |  224 lines

  1. /*
  2.  * move.c - support for Tablut game moves.
  3.  */
  4. #include <quickdraw.h>
  5. #include <window.h>
  6. #include <memory.h>
  7. #include "tablut.h"
  8.  
  9. /*
  10.  * movepiece() - attempt to move the given piece to the given grid location.
  11.  *  Check the legality of the move;
  12.  *  if the move is illegal, put the piece back where it was...
  13.  *  otherwise, move the piece, record the move, and do any captures.
  14.  *  NOTE: in setup mode almost all moves are legal,
  15.  *    no moves are recorded, and no captures are made.
  16.  */
  17. movepiece(pidx, togridp)
  18. int pidx;        /* index of the piece to try to move    */
  19. Point *togridp;        /* grid coords to try to move to    */
  20. {
  21.     struct pieceimage *p;
  22.  
  23.     p = &piece[pidx];
  24.     if (!islegal(pidx, togridp)) { /* illegal move -- put it back */
  25.     if (!onboard(p)) removepiece(pidx);
  26.     else placepiece(pidx, p->grid.h, p->grid.v);
  27.     } else {
  28.     if (togridp->h == NOGRID) removepiece(pidx);
  29.     else placepiece(pidx, togridp->h, togridp->v);
  30.     if (!insetup) {
  31.         seecaptures(pidx); seeraichi(); writeboard();
  32.     }
  33.     }
  34. }
  35.  
  36. /*
  37.  * islegal() - given a piece and a place to move it, islegal returns 1
  38.  *  if that move is legal; 0 otherwise.
  39.  * NOTE: this routine assumes that findpiece() and dragpiece() have
  40.  *  weeded out a large set of possible illegal moves.  Islegal() only
  41.  *  has to weed out the moves that they can't.
  42.  */
  43. int
  44. islegal(pidx, togridp)
  45. int pidx;    /* index of the piece to try to move    */
  46. Point *togridp;    /* grid coords to try to move to    */
  47. {
  48.     struct pieceimage *p;
  49.  
  50.     p = &piece[pidx];
  51.     if (togridp->h == NOGRID) {
  52.     return(insetup);    /* moving off-board is legal only in setup */
  53.     }
  54.     if (EqualPt(pass(p->grid), pass(*togridp))) {
  55.     return(0);    /* already there -- that's no move */
  56.     }
  57.     if (togridp->h == 0 && togridp->v == 0 && p != &piece[THEKING]) {
  58.     return(0);    /* only the king can occupy the throne */
  59.     }
  60.     if ((*gridp)[togridp->h][togridp->v]) {
  61.     return(0);    /* can't move to an occupied square */
  62.     }
  63.     return(1);
  64. }
  65.  
  66. /*
  67.  * seecaptures() - examine the board for captures that were caused by
  68.  *  moving the given piece.
  69.  */
  70. seecaptures(pidx)
  71. int pidx;    /* index of the moved piece    */
  72. {
  73.     struct pieceimage *p;    /* pointer to the moved piece    */
  74.     short kh, kv;        /* grid coords of the king    */
  75.     short h, v;
  76.  
  77.     p = &piece[pidx];
  78.     h = p->grid.h; v = p->grid.v;
  79.     trycapture((*gridp)[h-2][v], (*gridp)[h-1][v], (*gridp)[h][v]);
  80.     trycapture((*gridp)[h][v-2], (*gridp)[h][v-1], (*gridp)[h][v]);
  81.     trycapture((*gridp)[h+2][v], (*gridp)[h+1][v], (*gridp)[h][v]);
  82.     trycapture((*gridp)[h][v+2], (*gridp)[h][v+1], (*gridp)[h][v]);
  83.     if (onboard(&piece[THEKING])) {
  84.     /*
  85.      * The king is captured if there is a circle
  86.      * of muscovites (or the throne) surrounding the king
  87.      * and the circle was completed by the current move.
  88.      */
  89.     kh = piece[THEKING].grid.h; kv = piece[THEKING].grid.v;
  90.     if (kingdanger(kh-1, kv) && kingdanger(kh, kv-1) &&
  91.       kingdanger(kh+1, kv) && kingdanger(kh, kv+1)) {
  92.         if ((*gridp)[kh-1][kv] == p || (*gridp)[kh][kv-1] == p ||
  93.           (*gridp)[kh+1][kv] == p || (*gridp)[kh][kv+1] == p) {
  94.         winner = BLACKWIN;
  95.         blinksquares(&(piece[THEKING].grid), 
  96.           &(piece[THEKING].grid));
  97.         }
  98.     }
  99.     }
  100. }
  101.  
  102. /*
  103.  * trycapture() - given three adjacent pieces (or nothing) see if the
  104.  * middle swede or muscovite (but not the swedish king) can be captured.
  105.  * If it can, remove it from the board.
  106.  */
  107. trycapture(pl, pc, pr)
  108. struct pieceimage *pl, *pc, *pr;    /* adjacent pieces to check */
  109. {
  110.     if (!pl || !pc || !pr) return;
  111.     if (whitepiece(pl) && blackpiece(pc) && whitepiece(pr)) {
  112.     removepiece((int)(pc - &piece[0])); return;
  113.     }
  114.     if (blackpiece(pl) && classbase(pc) == FIRSTSWEDE && blackpiece(pr)) {
  115.     removepiece((int)(pc - &piece[0])); return;
  116.     }
  117. }
  118.  
  119. /*
  120.  * kingdanger() - given grid coords of a position, see if there is direct
  121.  * danger to the king from that square -- I.E., see if that square is the
  122.  * throne or if it contains a black piece.
  123.  */
  124. int
  125. kingdanger(h, v)
  126. short h,v;    /* coords to check */
  127. {
  128.     if (h == 0 && v == 0) return(1);
  129.     if ((*gridp)[h][v] && blackpiece((*gridp)[h][v])) return(1);
  130.     return(0);
  131. }
  132.  
  133. /*
  134.  * seeraichi() - see if there is a Raichi or Tuichi
  135.  */
  136. seeraichi()
  137. {
  138.     Point minloc, maxloc;    /* bounds of the king's movement    */
  139.     Point raichis[4];        /* storage for raichi moves        */
  140.     Point *rp;            /* points to the next free raichi slot    */
  141.     Point kingloc;        /* the king's current grid coordinates    */
  142.     int numraichis;        /* number of raichis            */
  143.     int blockable;        /* "all raichis can be blocked"        */
  144.  
  145.     blockable = 1;
  146.     if (!onboard(&piece[THEKING])) return;
  147.     findbounds(THEKING, &minloc, &maxloc);
  148.     kingloc.h = piece[THEKING].grid.h; kingloc.v = piece[THEKING].grid.v;
  149.     rp = &raichis[0];
  150.     if (minloc.h == -4) {
  151.     SetPt(rp++, -4, kingloc.v);
  152.     blockable &= vblock(kingloc.v, -4, kingloc.h - 1);
  153.     }
  154.     if (minloc.v == -4) {
  155.     SetPt(rp++, kingloc.h, -4);
  156.     blockable &= hblock(kingloc.h, -4, kingloc.v - 1);
  157.     }
  158.     if (maxloc.h == 4) {
  159.     SetPt(rp++, 4, kingloc.v);
  160.     blockable &= vblock(kingloc.v, kingloc.h + 1, 4);
  161.     }
  162.     if (maxloc.v == 4) {
  163.     SetPt(rp++, kingloc.h, 4);
  164.     blockable &= hblock(kingloc.h, kingloc.v + 1, 4);
  165.     }
  166.     numraichis = (int)(rp - &raichis[0]);
  167.     if (numraichis >= 1) blinksquares(&raichis[0], rp - 1);
  168.     if (numraichis >= 2 || !blockable || (blacksmove() && numraichis >= 1)) {
  169.     winner = WHITEWIN;
  170.     }
  171. }
  172.  
  173. /*
  174.  * vblock(), hblock() - see if the given row (or column) can be blocked by
  175.  *  a black piece.  This routine is used to see if a Raichi is blockable.
  176.  */
  177. int
  178. vblock(kv, fromh, toh)
  179. short kv;        /* the row to be examined (the king's row) */
  180. short fromh, toh;        /* the bounds of the part to be blocked       */
  181. {
  182.     short h,v;        /* grid square being examined for a piece  */
  183.  
  184.     for (h = fromh; h <= toh; ++h) {
  185.     for (v = kv - 1; v >= -4; --v) {
  186.         if ((*gridp)[h][v]) {
  187.         if (blackpiece((*gridp)[h][v])) return(1);
  188.         else break;
  189.         }
  190.     }
  191.     for (v = kv + 1; v <= 4; ++v) {
  192.         if ((*gridp)[h][v]) {
  193.         if (blackpiece((*gridp)[h][v])) return(1);
  194.         else break;
  195.         }
  196.     }
  197.     }
  198.     return(0);
  199. }
  200.  
  201. int
  202. hblock(kh, fromv, tov)
  203. short kh;        /* the col to be examined (the king's col) */
  204. short fromv, tov;        /* the bounds of the part to be blocked       */
  205. {
  206.     short h,v;        /* grid square being examined for a piece  */
  207.  
  208.     for (v = fromv; v <= tov; ++v) {
  209.     for (h = kh - 1; h >= -4; --h) {
  210.         if ((*gridp)[h][v]) {
  211.         if (blackpiece((*gridp)[h][v])) return(1);
  212.         else break;
  213.         }
  214.     }
  215.     for (h = kh + 1; h <= 4; ++h) {
  216.         if ((*gridp)[h][v]) {
  217.         if (blackpiece((*gridp)[h][v])) return(1);
  218.         else break;
  219.         }
  220.     }
  221.     }
  222.     return(0);
  223. }
  224.